/*
 * 基于muduo网络库和Protobuf协议实现的多功能服务器
 * 功能：
 * 1. 支持翻译请求（中英互译）
 * 2. 支持加法运算请求
 * 3. 自动处理未知协议类型
 */

// 包含必要的头文件
#include "muduo/proto/codec.h"       // Protobuf编解码器
#include "muduo/proto/dispatcher.h"  // Protobuf消息分发器
#include "muduo/base/Logging.h"      // 日志系统
#include "muduo/base/Mutex.h"        // 互斥锁
#include "muduo/net/EventLoop.h"     // 事件循环
#include "muduo/net/TcpServer.h"     // TCP服务器

#include "request.pb.h"              // Protobuf生成的消息头文件
#include <iostream>
#include <unordered_map>

class Server 
{
public:
    // 定义Protobuf消息智能指针类型
    typedef std::shared_ptr<google::protobuf::Message> MessagePtr;
    typedef std::shared_ptr<bit::TranslateRequest> TranslateRequestPtr;
    typedef std::shared_ptr<bit::AddRequest> AddRequestPtr;

    
    // 构造函数：初始化服务器组件
    Server(int port): 
        _server(&_baseloop, muduo::net::InetAddress("0.0.0.0", port), 
                "Server", muduo::net::TcpServer::kReusePort),  // 创建TCP服务器
        _dispatcher(std::bind(&Server::onUnknownMessage, this,   // 初始化消息分发器
                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
        _codec(std::bind(&ProtobufDispatcher::onProtobufMessage, &_dispatcher,  // 初始化编解码器
                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3))
    {
        // 注册消息处理回调
        _dispatcher.registerMessageCallback<bit::TranslateRequest>(
            std::bind(&Server::onTranslate, this, 
                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
            
        _dispatcher.registerMessageCallback<bit::AddRequest>(
            std::bind(&Server::onAdd, this, 
                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

        // 设置网络层回调
        _server.setMessageCallback(std::bind(&ProtobufCodec::onMessage, &_codec,
            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
        _server.setConnectionCallback(std::bind(&Server::onConnection, this, std::placeholders::_1));
    }

    // 启动服务器
    void start() {
        _server.start();    // 启动TCP监听
        _baseloop.loop();   // 进入事件循环
    }

private:
    // 翻译功能实现
    std::string translate(const std::string &str) {
        // 静态字典，存储翻译词库
        static std::unordered_map<std::string, std::string> dict_map = {
            {"hello", "你好"},    // 英文转中文
            {"Hello", "你好"},     // 支持不同大小写
            {"你好", "Hello"},     // 中文转英文
            {"吃了吗", "油泼面"}    // 趣味翻译
        };

        auto it = dict_map.find(str);
        return (it == dict_map.end()) ? "没听懂！！" : it->second;
    }

    // 处理翻译请求
    void onTranslate(const muduo::net::TcpConnectionPtr& conn, 
                    const TranslateRequestPtr& message, 
                    muduo::Timestamp) 
    {
        // 1. 提取请求内容
        std::string req_msg = message->msg();
        
        // 2. 执行翻译
        std::string rsp_msg = translate(req_msg);
        
        // 3. 构造并发送响应
        bit::TranslateResponse resp;
        resp.set_msg(rsp_msg);
        _codec.send(conn, resp);  // 通过编解码器发送响应
    }

    // 处理加法请求
    void onAdd(const muduo::net::TcpConnectionPtr& conn, 
              const AddRequestPtr& message, 
              muduo::Timestamp) 
    {
        // 1. 解析请求参数
        int num1 = message->num1();
        int num2 = message->num2();
        
        // 2. 执行计算
        int result = num1 + num2;
        
        // 3. 构造并发送响应
        bit::AddResponse resp;
        resp.set_result(result);
        _codec.send(conn, resp);
    }

    // 处理未知消息类型
    void onUnknownMessage(const muduo::net::TcpConnectionPtr& conn, 
                         const MessagePtr& message, 
                         muduo::Timestamp) 
    {
        LOG_INFO << "收到未知协议类型: " << message->GetTypeName();
        conn->shutdown();  // 安全关闭连接
    }

    // 处理连接状态变化
    void onConnection(const muduo::net::TcpConnectionPtr &conn) {
        if (conn->connected()) {
            LOG_INFO << "新客户端连接: " << conn->peerAddress().toIpPort();
        } else {
            LOG_INFO << "连接关闭: " << conn->peerAddress().toIpPort();
        }
    }

private:
    // 核心组件
    muduo::net::EventLoop _baseloop;    // 事件循环（Reactor核心）
    muduo::net::TcpServer _server;      // TCP服务器
    ProtobufDispatcher _dispatcher;     // 消息分发路由器
    ProtobufCodec _codec;               // 协议编解码器
};

int main()
{
    // 创建并启动服务器
    Server server(8888);          // 监听8888端口
    LOG_INFO << "服务器启动，监听端口 8888...";
    server.start();               // 进入事件循环
    
    return 0;
}